#include "clib_signal.h"
#define _XOPEN_SOURCE 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#undef _XOPEN_SOURCE

static clib_signal_t signals[256] = {};

static void
clib_signals_handler(i32_t signo) 
{
    signal_fn     handle;
    clib_signo_type_t type = clib_signo_type_ignore;
    clib_signal_t *sig = &signals[signo];
    for(int i = 0; i < CLIB_HANDLE_MAX; i++) {
        handle = sig->call[i];
        if(!handle) {
            break;
        }
        type |= handle(signo);
    }

    if(type) {
        exit(0);
    }
}

i32_t
clib_register_signal(i32_t signo,signal_fn handle)
{
    clib_signal_t *sig = &signals[signo];

    sig->signo = signo;

    for(int i = 0; i < CLIB_HANDLE_MAX; i++) {
        if(!sig->call[i]) {
            sig->call[i] = handle;
            return 0;
        }
    }
    return -1;
}   

void
clib_register_signal_by_cfg(clib_signal_t *signal,i32_t nums) 
{
    clib_signal_t *sig;
    for(int i = 0 ; i < nums; i++) {
        sig = &signal[i];

        if(!signals[sig->signo].name) {
            signals[sig->signo].name = sig->name;
            signals[sig->signo].signame = sig->signame;
        }

        for(int j = 0; j < CLIB_HANDLE_MAX; j++) {
            
            if(!sig->call[j]) {
                clib_register_signal(sig->signo,sig->call[j]);
                break;
            }
        }
    }
}

void
clib_init_signal()
{
    struct sigaction sa;
    clib_signal_t    *sig;
    for(int i = 0; i < 256; i++) {
        sig = &signals[i];
        if(sig->name && sig->call[0]) {
            memset(&sa, 0, sizeof(struct sigaction));
            sa.sa_handler = clib_signals_handler;
            sigemptyset(&sa.sa_mask);
            if (sigaction(sig->signo, &sa, NULL) == -1) {
                return ;
            }
        }
    }
}
